#pragma once
#include "DXAMLCommon.h"
#include "IPALExecuteOnUIThread.h"
#include "CXcpList.h"
#include "REQUEST.h"
#include "xchainedmap.h"
#include "IScriptObject.h"

class CDependencyObject;
class CDependencyProperty;
class CEventArgs;
class CValue;
class CRoutedEventArgs;
class CControl;
class CUIElement;
class Xcp_IDependencyObject;

class CEventManager :
	public IObject,
	public IPALExecuteOnUIThread
{


public: 
	static HRESULT Create(struct ICoreServices * pCore, CEventManager * * ppObject);
	virtual XUINT32 AddRef();
	virtual XUINT32 Release();
	virtual HRESULT Execute();
	HRESULT AddRequestsInOrder(CDependencyObject * pObject, CXcpList<REQUEST> * pEventList);
	HRESULT RemoveRequests(CDependencyObject * pObject, CXcpList<REQUEST> * pEventList);
	HRESULT AddRequest(CDependencyObject * pObject, struct REQUEST * pRequest);
	HRESULT RemoveRequest(CDependencyObject * pObject, struct REQUEST * pRequest);
	HRESULT RemoveObject(CDependencyObject * pObject);
	HRESULT CreateRequest(struct REQUEST * * ppRequest, CDependencyProperty * pEvent, CDependencyObject * pObject, CValue * pValue, XINT32 iToken, CCoreServices * pContext, XINT32 fHandledEventsToo);
	HRESULT ClearRequests();
	HRESULT ClearRequests(CDependencyProperty *, CDependencyObject *);
	void Raise(CDependencyProperty * pEvent, XINT32 bRefire, CDependencyObject * pSender, CEventArgs * pArgs, XBOOL fRaiseSync, XBOOL fInputEvent, XBOOL bAllowErrorFallback, CDependencyObject * pSenderOverride);
	void RaiseRoutedEvent(CDependencyProperty * pEvent, CDependencyObject * pSource, CRoutedEventArgs * pArgs, XINT32 bIgnoreVisibility, XBOOL fRaiseSync, XBOOL fInputEvent);
	void ThreadSafeRaise(CDependencyProperty * pEvent, XINT32 bRefire, CDependencyObject * pSender, CEventArgs * * ppArgs, XBOOL fAllowErrorFallback, XBOOL fUseFastRaise);
	void RaiseCallback(CEventArgs * pArgs);
	HRESULT ProcessQueue(XBOOL fProcessFastQueue);
	HRESULT FlushQueue();
	HRESULT Disable();
	XBOOL ShouldRaiseLoadedEvent();
	HRESULT RequestRaiseLoadedEventOnNextTick();
	HRESULT RaiseLoadedEvent();
	static HRESULT AddEventListener(CDependencyObject * pDO, CXcpList<REQUEST> * * pEventList, CDependencyProperty * pdp, CValue * pValue, XINT32 iListenerType, CValue * pResult, XINT32 fHandledEventsToo, XBOOL fSkipIsActiveCheck);
	static HRESULT RemoveEventListener(CDependencyObject * pDO, CXcpList<REQUEST> * pEventList, CDependencyProperty * pdp, CValue * pValue, XBOOL fSkipIsActiveCheck);
	static XBOOL IsValidJavascriptName(XUINT32 cName, XUINT16 * pName);

	typedef HRESULT (* PFNScriptCallbackA)(Xcp_IDependencyObject *, Xcp_IDependencyObject *);
	typedef HRESULT (*PFNScriptCallback)(void *, Xcp_IDependencyObject *, Xcp_IDependencyObject *, CXString *, int, IScriptObject *, PFNScriptCallbackA *);
	void * m_pControl;
	//class xvector<REQUEST *>
	//class xchainedmap<CDependencyObject *,xvector<REQUEST *> *>
	//class xvector<CDependencyObject *>

private: 
	CEventManager();
	~CEventManager();
	void RaiseControlEvents(CDependencyProperty * pEvent, CControl * pSender, CEventArgs * pArgs, PFNScriptCallback  * pfnScriptCallback);
	void RaiseUIElementEvents(CDependencyProperty * pEvent, CUIElement * pSender, CEventArgs * pArgs, PFNScriptCallback  * pfnScriptCallback);
	HRESULT RaiseHelper(xvector<REQUEST *> * pRegisteredRequests, CDependencyProperty * pEvent, CDependencyObject * pSender, CEventArgs * pArgs, XINT32 bRefire, PFNScriptCallback  * pfnScriptCallback, XUINT32 & bFired, CDependencyObject * pSenderOverride);
	HRESULT AddToLoadedEventList(CDependencyObject * pElement);
	HRESULT RemoveFromLoadedEventList(CDependencyObject * pElement);
	XBOOL IsLoadedEvent(CDependencyProperty * pEvent);
	XBOOL IsSyncInputEvent(CDependencyProperty * pEvent);
	XBOOL IsKeyEvent(CDependencyProperty * pEvent);
	HRESULT ProcessQueueImpl(struct IPALQueue * pQueue);
	static XBOOL DoesElementAllowHandlerWhenNotLive(CDependencyObject * pDO);
	void EnsureSenderAndArgsUnpegged(CDependencyObject * pSender, CRoutedEventArgs * pArgs, XUINT32 flags);
	HRESULT RequestAdditionalFrame();
	XUINT32 m_cRef;
	xchainedmap<CDependencyObject *,xvector<REQUEST *> *> * m_pRequest;
	XUINT32 m_cRequestAllocated;
	struct IPALQueue * m_pSlowQueue;
	struct IPALQueue * m_pFastQueue;
	XINT32 m_iNextToken;
	xvector<CDependencyObject *> * m_pLoadedEventList;
	XUINT32 m_uInClearRequests;
	struct ICoreServices * m_pCore;
	XBOOL m_fRaiseLoadedEventNeeded;

	struct RaiseArguments
	{
	public: 
		CDependencyProperty * m_pEvent;
		XINT32 m_bRefire;
		CDependencyObject * m_pSender;
		CEventArgs * m_pArgs;
		XBOOL m_fAllowErrorFallback;
		RaiseArguments(CDependencyProperty * pEvent, XINT32 bRefire, CDependencyObject * pSender, CEventArgs * * ppArgs, XBOOL fAllowErrorFallback);
		~RaiseArguments();
	};


};

